#include <iostream>
#include <sstream>
#include <future>
#include <chrono>
#include <bhttpclient/bclient.h>
#include <bhttpclient/client.h>
#include <Windows.h>
#include "uis_request.h"
#include "huawei.h"

#ifdef _WIN64
#pragma comment(lib,"../bhttpclient/libcurl/lib/x64/libcurl.lib")
#else
#pragma comment(lib,"../bhttpclient/libcurl/lib/x86/libcurl.lib")
#endif

std::shared_ptr<bhttp::client> httpclient;

void test_get(std::promise<int>& p)
{
    auto req = std::make_shared<bhttp::brequest>();
    req->url("https://www.baidu.com");
    bhttp::bclient::instance()->send(req, [&p](const bhttp::brequest_ptr& req, const bhttp::bresponse_ptr& rep) {
        do
        {
            if (!rep->successed())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error();
                break;
            }
            if (200 != rep->code())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_as_string();
                break;
            }
            //std::string cookie = rep->header("Set-Cookie");
            //std::string heads = std::string(rep->headers().data(), rep->headers().size());
            //std::cout << "HTTP完成:" << std::endl
            //    << "Head=>" << heads << std::endl
            //    << "Body=>" << rep->body_as_string() << std::endl;
        } while (false);
        p.set_value(rep->code());
    });
}

void test_get1()
{
    //auto req = std::make_shared<bhttp::brequest>();
    //req->url("https://www.baidu.com");
    //bhttp::bclient::instance()->send(req, [](const bhttp::brequest_ptr& req, const bhttp::bresponse_ptr& rep) {

    //});
    auto req = std::make_shared<bhttp::request>();
    httpclient->send(req, [](const bhttp::request_ptr& req, const bhttp::response_ptr& rep) {
        do
        {
            std::cout << "1--------------------" << rep.use_count() << std::endl;
            if (!rep->successed())
            {
                std::cout << req->path() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error() << std::endl;
                break;
            }
            if (200 != rep->code())
            {
                std::cout << req->path() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_string() << std::endl;
                break;
            }
        } while (false);
    });
}
void test_get2()
{
    auto req = std::make_shared<bhttp::request>();
    httpclient->send(req, [](const bhttp::request_ptr& req, const bhttp::response_ptr& rep) {
        do
        {
            std::cout << "2--------------------" << rep.use_count() << std::endl;
            if (!rep->successed())
            {
                std::cout << req->path() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error() << std::endl;
                break;
            }
            if (200 != rep->code())
            {
                std::cout << req->path() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_string() << std::endl;
                break;
            }
        } while (false);
    });
}

void test_put(std::promise<int>& p)
{
    auto req = std::make_shared<bhttp::brequest>();
    req->method(bhttp::brequest::type::PUT);
    req->header("Token", "d6e096f4fda32a87e4f5a1301bac253b2d157dbd69723397fcbe0610c83cf3c4");
    req->url("https://172.16.149.253/conf-portal/tokens?grantType=refresh");
    bhttp::bclient::instance()->timeout_connect(5);
    bhttp::bclient::instance()->send(req, [&p](const bhttp::brequest_ptr& req, const bhttp::bresponse_ptr& rep) {
        do
        {
            if (!rep->successed())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error();
                break;
            }
            if (200 != rep->code())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_as_string();
                break;
            }
            std::string cookie = rep->header("Set-Cookie");
            std::string heads = std::string(rep->headers().data(), rep->headers().size());
            std::cout << "HTTP完成:" << std::endl
                << "Head=>" << heads << std::endl
                << "Body=>" << rep->body_as_string() << std::endl;
        } while (false);
        p.set_value(rep->code());
    });
}

void test_patch(std::promise<int>& p)
{
    auto req = std::make_shared<bhttp::brequest>();
    req->method(bhttp::brequest::type::PATCH);
    req->header("Content-Type", "application/json");
    req->header("Token", "d6e096f4fda32a87e4f5a1301bac253b2d157dbd69723397fcbe0610c83cf3c4");
    req->body(R"({"chairman" : "4ad1fb8d-9c7f-4096-9c3d-f7b8de78928f", "isOnline" : true, "mode" : "FREE_MODE" })");
    req->url("https://172.16.149.253/conf-portal/online/conferences/7df138a5-3dfd-4dff-90ec-e4182c43eba2/status");
    bhttp::bclient::instance()->send(req, [&p](const bhttp::brequest_ptr& req, const bhttp::bresponse_ptr& rep) {
        do
        {
            if (!rep->successed())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error();
                break;
            }
            if (204 != rep->code())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_as_string();
                break;
            }
            std::string cookie = rep->header("Set-Cookie");
            std::string heads = std::string(rep->headers().data(), rep->headers().size());
            std::cout << "HTTP完成:" << std::endl
                << "Head=>" << heads << std::endl
                << "Body=>" << rep->body_as_string() << std::endl;
        } while (false);
        p.set_value(rep->code());
    });
}

void test_del(std::promise<int>& p)
{
    auto req = std::make_shared<bhttp::brequest>();
    req->method(bhttp::brequest::type::DEL);
    req->header("Token", "d6e096f4fda32a87e4f5a1301bac253b2d157dbd69723397fcbe0610c83cf3c4");
    req->url("https://172.16.149.253/conf-portal/online/conferences/7df138a5-3dfd-4dff-90ec-e4182c43eba2");
    bhttp::bclient::instance()->send(req, [&p](const bhttp::brequest_ptr& req, const bhttp::bresponse_ptr& rep) {
        do
        {
            if (!rep->successed())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error();
                break;
            }
            if (204 != rep->code())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_as_string();
                break;
            }
            std::string cookie = rep->header("Set-Cookie");
            std::string heads = std::string(rep->headers().data(), rep->headers().size());
            std::cout << "HTTP完成:" << std::endl
                << "Head=>" << heads << std::endl
                << "Body=>" << rep->body_as_string() << std::endl;
        } while (false);
        p.set_value(rep->code());
    });
}

void test_uis(std::promise<int>& p)
{
    auto req = std::make_shared<uis::request>();
    req->url("http://192.168.4.246:10090/rcsss/message/getClientInfoList");
    bhttp::bclient::instance()->send(req, [&p](const bhttp::brequest_ptr& req, const bhttp::bresponse_ptr& rep) {
        do
        {
            if (!rep->successed())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Error: " << rep->error();
                break;
            }
            if (200 != rep->code())
            {
                std::cout << req->url() << " 请求失败=> Code:" << rep->code() << ", Body: " << rep->body_as_string();
                break;
            }
            std::string cookie = rep->header("Set-Cookie");
            std::string heads = std::string(rep->headers().data(), rep->headers().size());
            std::cout << "HTTP完成:" << std::endl
                << "Head=>" << heads << std::endl
                << "Body=>" << rep->body_as_string() << std::endl;
        } while (false);
        p.set_value(rep->code());
    });
}

class benchmark
{
public:
    benchmark() { }
    ~benchmark() {
        const auto& dur = std::chrono::system_clock::now() - begin_;
        std::cout << "耗时(ms): " << std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() << std::endl;
    }
    benchmark(const benchmark&) = delete;
    benchmark &operator=(const benchmark&) = delete;

private:
    std::chrono::time_point<std::chrono::system_clock> begin_ = std::chrono::system_clock::now();
};

int main(int argc, char* argv[])
{
#ifdef _WIN32
    // 设置控制台编码为UTF-8
    SetConsoleOutputCP(CP_UTF8);
#endif

    std::cout << "输入对应字符，进行测试:" << std::endl;
    std::cout << "GET请求(1):" << std::endl;
    std::cout << "PUT请求(2):" << std::endl;
    std::cout << "PATCH请求(3):" << std::endl;
    std::cout << "POST测试UIS(4):" << std::endl;
    std::cout << "DELETE测试(5):" << std::endl;
    std::cout << "退出(q/其他):" << std::endl;
    httpclient = std::make_shared<bhttp::client>("https://www.baidu.com");
    char inc = 0;
    while (std::cin) {
        // 声明一个promise, 保证HTTP接口执行完成
        std::promise<int> p;
        // 将future和promise关联
        std::future<int> f = p.get_future();

        std::cout << "请输入:";
        std::cin >> inc;
        // 计算耗时
        benchmark bk;
        if (inc == '1')
            test_get(std::ref(p));
        else if (inc == '2')
            test_put(std::ref(p));
        else if (inc == '3')
            test_patch(std::ref(p));
        else if (inc == '4')
            test_uis(std::ref(p));
        else if (inc == '5')
            test_del(std::ref(p));
        else if (inc == '6') {
            for (int i = 0; i < 10; i++)
            {
                if (i % 2 == 0)
                {
                    std::thread t(test_get1);
                    t.detach();
                }
                else
                {
                    std::thread t(test_get2);
                    t.detach();
                }
            }
            p.set_value(0);
        } 
        else if (inc == '7') {
            huawei hw;
            hw.start();
            p.set_value(0);
        }
        else {
            p.set_value(0);
            break;
        }
        // 等待future
        if (f.valid()) f.get();
    }
    return 0;
}
